#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <db.h>
#include "uniondef.h"

#define SHORT_OPTION_STRING "i:t:p:s:n:d:o:f:"

struct option long_options[] =
{
    /* options */
    {"patternID", required_argument, 0, 'i'},
    {"patternType", required_argument, 0, 't'},
    {"initPos", required_argument, 0, 'p'},
    {"initSize", required_argument, 0, 's'},
    {"numRep", required_argument, 0, 'n'},
    {"strideSize", required_argument, 0, 'd'},
    {"operation", required_argument, 0, 'o'},
    {"filename", required_argument, 0, 'f'},
    {0, 0, 0, 0}
};

int parseArgs (int argc, const char * argv[], AccessPattern * ptn, char * idString, char * filename) 
{
    int c;

    while (1) {
        int option_index = 0;

        c = getopt_long(argc, (const char * *)argv, SHORT_OPTION_STRING, long_options, &option_index);

        /* detect the end of the options */
        if (c == -1)
        {
            break;
        }

        switch (c)
        {
            case 0:
                /* flags */
                break;
            case '?':
                /* unrecognized */
                break;

            case 'i':
                strcpy(idString, optarg);
                break;
            case 't':
                ptn->patternType = atoi(optarg);
                break;
            case 'p':
                ptn->initPos = atoi(optarg);
                break;
            case 's':
                ptn->initSize = atoi(optarg);
                break;
            case 'n':
                ptn->numRep = atoi(optarg);
                break;
            case 'd':
                ptn->strideSize = atoi(optarg);
                break;
            case 'o':
                ptn->operation = atoi(optarg);
                break;
            case 'f':
                strcpy(filename, optarg);
                break;

            default:
                exit(1);
        }

    } /* end of while (1) */
    return 0;
}

int main (int argc, const char * argv[]) 
{
    AccessPattern ptn;
    unsigned len;                  // Length of serialized data
    char patternID[256];
    //char filename[1024];

    DB *dbp;              /* DB structure handle */
    DBT key, value;
    unsigned int flags;   /* database open flags */
    int ret;              /* function return value */

    memset(patternID, 0, 256);
    memset(&ptn, 0, sizeof(AccessPattern));
    fprintf(stdout, "sizeof accessPattern: %d \n", sizeof(AccessPattern));

    parseArgs(argc, argv, &ptn, (char *)patternID, (char *)ptn.filename);

    /* Initialize db structure. */
    ret = db_create(&dbp, NULL, 0);
    if (ret != 0) {
        fprintf(stderr, "Error initializing DB\n", len);
        exit(1);
    }

    /* DB open flags */
    flags = DB_CREATE;

    /* open DB */
    ret = dbp->open(dbp, NULL, "/mnt/common/yyin/PDLA/patterndb.db", NULL, DB_HASH, flags, 0);
    //ret = dbp->open(dbp, NULL, "my.db", NULL, DB_HASH, flags, 0);
    if (ret != 0) {
        fprintf(stderr, "dbp->open: %s\n", db_strerror(ret));
        if (dbp != NULL) {
            dbp->close(dbp, 0);
        }
        exit(1);
    }

    memset(&key, 0, sizeof(DBT));
    memset(&value, 0, sizeof(DBT));

    key.data = (uint8_t *)patternID;
    key.size = strlen(patternID)+1;

    value.data = (uint8_t *)&ptn;
    value.size = sizeof(AccessPattern); 

    /*
       fprintf(stdout, "Writing %d serialized bytes\n", len);
       fprintf(stdout, "[INFO]\tkey.data: %d\n", *((int *)(key.data))); 
       fprintf(stdout, "[INFO]\tkey.size: %lu\n", sizeof(int)); 
       fprintf(stdout, "[INFO]\tvalue.size: %d\n", value.size); 
     */

    ret = dbp->put(dbp, NULL, &key, &value, 0);
    if (ret != 0) {
        fprintf(stderr, "Error putting ...\n");
        if (dbp != NULL) {
            dbp->close(dbp, 0);
        }
        exit(1);
    }

    dbp->sync(dbp, 0);
    /* close DB */
    if (dbp != NULL)
        dbp->close(dbp, 0);

    return 0;
}

///:~

